const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');
// TODO: Consider using a more robust TS parser like ts-morph for better type safety

const apiDir = path.join(__dirname, '../src/main/api');
// 假设生成的客户端代码放在这里
const outputFilePath = path.join(__dirname, '../src/renderer/src/api/backend-api.ts');

// 简单的 kebab-case 转换函数
function toKebabCase(str) {
  return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
}

// 递归查找目录下的所有 .ts 文件
function findTsFiles(directory) {
  let tsFiles = [];
  const files = fs.readdirSync(directory);

  for (const file of files) {
    const filePath = path.join(directory, file);
    const stat = fs.statSync(filePath);

    if (stat.isDirectory()) {
      tsFiles = tsFiles.concat(findTsFiles(filePath));
    } else if (stat.isFile() && file.endsWith('.ts')) {
      tsFiles.push(filePath);
    }
  }
  return tsFiles;
}

// 根据文件路径生成 IPC channel 名称的基础部分 (不包含函数名)
function generateChannelBase(filePath) {
  // 获取相对于 apiDir 的路径
  const relativePath = path.relative(apiDir, filePath);
  // 移除 .ts 扩展名
  const baseName = relativePath.replace(/\.ts$/, '');
  // 将路径分隔符转换为 / 并分割
  const parts = baseName.split(/[\\/]/);

  // 添加 'api' 前缀，并转换为 kebab-case
  const channelParts = ['api', ...parts].map(toKebabCase);

  return '/' + channelParts.join('/'); // 地址统一使用 / 开头
}

// 根据文件路径生成客户端对象结构路径
function generateClientObjectPath(filePath) {
  // 获取相对于 apiDir 的路径
  const relativePath = path.relative(apiDir, filePath);
  // 移除 .ts 扩展名
  const baseName = relativePath.replace(/\.ts$/, '');
  // 将路径分隔符转换为 . 并分割，保留文件名部分（即使是 index）
  const parts = baseName.split(/[\\/]/).filter((part) => part); // 过滤空字符串，保留 index
  // 不再添加 'Api' 前缀，只返回相对路径部分
  return parts;
}

async function generateApiClient() {
  console.log(`[generate-api] Scanning API directory: ${apiDir}`);
  const tsFiles = findTsFiles(apiDir);
  console.log(`[generate-api] Found ${tsFiles.length} TS files.`);

  let generatedCode = `// This file is auto-generated by scripts/generate-api-client.js\n`;
  generatedCode += `// Do not modify this file directly.\n\n`;
  generatedCode += `import { invokeBackend } from '@/api/request';\n\n`; // 修改导入语句

  // 构建 API 对象结构
  const apiStructure = {};

  for (const filePath of tsFiles) {
    const channelBase = generateChannelBase(filePath);
    // 获取对象路径部分，不包含顶层 'Api'
    const objectPathParts = generateClientObjectPath(filePath);
    console.log(
      `[generate-api] Processing ${filePath} -> Channel Base: ${channelBase}, Object Path: ${objectPathParts.join('.')}`
    );

    const fileContent = fs.readFileSync(filePath, 'utf-8');
    // 简单的正则匹配导出的函数声明，包括async函数
    const functionMatches = fileContent.matchAll(/^export\s+(async\s+)?function\s+(\w+)\s*\(/gm);

    let currentLevel = apiStructure;
    // 确保对象路径存在
    for (let i = 0; i < objectPathParts.length; i++) {
      const part = objectPathParts[i];
      if (!currentLevel[part]) {
        currentLevel[part] = {};
      }
      currentLevel = currentLevel[part];
    }

    let functionsFound = [];
    for (const match of functionMatches) {
      const functionName = match[2];
      functionsFound.push(functionName);
      console.log(`[generate-api]   Found function: ${functionName}`);

      // 生成客户端调用代码字符串，使用 invokeBackend
      const clientFunctionCode = `(...args: any[]) => {\n  return invokeBackend('${channelBase}/${toKebabCase(functionName)}', ...args);\n}`; // 修改为 invokeBackend

      // 将函数代码字符串添加到对象结构中
      currentLevel[functionName] = clientFunctionCode;
    }

    if (functionsFound.length === 0) {
      console.log(`[generate-api]   No exported functions found with simple regex in ${filePath}.`);
    }
  }

  // Recursive function to generate TypeScript code string from the structure
  function generateObjectCode(obj, level = 0) {
    const indent = '  '.repeat(level);
    const innerIndent = '  '.repeat(level + 1);

    const properties = [];
    for (const key in obj) {
      if (Object.hasOwnProperty.call(obj, key)) {
        const value = obj[key];
        if (typeof value === 'string') {
          // This is a function code string
          // Format: propertyName: (...args: any[]) => { ... }
          properties.push(`${innerIndent}${key}: ${value}`);
        } else {
          // This is a nested object/namespace
          // Recursively generate code for the nested object
          const nestedContent = generateObjectCode(value, level + 1).trim();
          // Format: propertyName: { ... }
          // Consistent formatting for nested objects
          properties.push(`${innerIndent}${key}: {${nestedContent}\n${innerIndent}}`);
        }
      }
    }

    const innerCode = properties.join(',\n');

    if (level === 0) {
      // Top level export should be 'export const Api'
      return `export default {\n${innerCode}\n${indent}};\n`; // Top level default export
    } else {
      // Nested object
      return `${innerCode}`; // Return content within braces for nesting
    }
  }

  // Start generating from the root apiStructure
  // apiStructure现在直接代表 { config: { index: { ... } }, test: { index: { ... } } }
  generatedCode += generateObjectCode(apiStructure);

  fs.writeFileSync(outputFilePath, generatedCode, 'utf-8');
  console.log(`[generate-api] API client generated at ${outputFilePath}`);

  // 使用 Prettier 格式化生成的文件
  try {
    console.log(`[generate-api] Formatting ${outputFilePath} with Prettier...`);
    execSync(`npx prettier --write "${outputFilePath}"`, {
      stdio: 'inherit',
      cwd: path.join(__dirname, '..')
    });
    console.log(`[generate-api] File formatted successfully with Prettier`);
  } catch (error) {
    console.warn(`[generate-api] Warning: Failed to format file with Prettier:`, error.message);
    console.warn(`[generate-api] The file was generated but not formatted. You can manually run: npm run format`);
  }
}

// 允许直接运行脚本进行测试
if (require.main === module) {
  generateApiClient().catch(console.error);
} else {
  // 导出函数供 watch 脚本调用
  module.exports = generateApiClient;
}
